<?php


namespace App\Web\Model;

use App\Web\Model\Customer as CustomerModel;
use EchoPHP\Facades\Db;
use EchoPHP\Facades\Redis;
use RuntimeException;

class CaseFlow extends Model {

    /**
     * 获取默认职位流程
     * @param bool $frontend 是否固化流程
     * @return mixed
     * @throws \Exception
     */
    public function getDefaultFlow($frontend = false) {
        // 前端不可拖拽
        //前端位置固定, 目前只有 01 加入项目 一定在流程开始，后续如果有其他流程位置固定，在此处添加即可，如后续开始流程一定是 加入项目-> 简历推荐 ，中间不能插入其他流程，则此数组加 '02' => 2
        $fixedList = [
            '01' => 1
        ];
        $caseFlowList = config('app.global_caseflow');
        if (!is_file($caseFlowList)) {
            throw new RuntimeException('职位流程未定义');
        }
        $caseFlow = include $caseFlowList;
        $default = [];
        foreach ($caseFlow as $code => $value) {
            $item = [
                'name' => $value['name'],
                'code' => $code,
                'isnecessary' => false,
                'listindex' => $value['listindex']
            ];
            if ($frontend) {
                $item['fixed'] = $fixedList[$code] ?? '';
            }
            foreach ($value['child'] as $childCode => $childItem) {
                $childItem['code'] = $childCode;
                $item['child'][$childCode] = $childItem;
                $item['isnecessary'] = $item['isnecessary'] || $childItem['iskpi'];
            }
            $default[$code] = $item;
        }
        return $default;
    }

    /**
     * 获取客户流程列表
     * @param $subId
     * @return array|mixed
     * @throws \Exception
     */
    public function getSubFlowCode($subId) {
        if ($subId <= 0) {
            return [];
        }
        $sql = 'SELECT tagcodelist FROM SubFlow WHERE subid=? AND status=?';
        $var = [$subId, '01'];
        $subFlowList = Db::selectOne($sql, $var);
        return $subFlowList;
    }

    /**
     * 获取客户的项目流程明细
     * @param $subId
     * @param bool $withNoChose 包含为选择的
     * @return array
     * @throws \Exception
     */
    public function getSubFlowFull($subId, $withNoChose = false) {
        if ($subId <= 0) {
            return [];
        }
        $result = (new CustomerModel())->myCostumer(['subid' => $subId]);
        if (empty($result) || !in_array($subId, array_column($result, 'subid'))) {
            return [];
        }
        $sql = 'SELECT tagcodelist FROM SubFlow WHERE subid=? AND status=?';
        $var = [$subId, '01'];
        $subFlowList = Db::selectOne($sql, $var);
        if (empty($subFlowList)) {
            return [];
        }
        $subFlowList = $subFlowList['tagcodelist'];
        $subFlowList = explode(',', $subFlowList);
        $defaultFlow = $this->getDefaultFlow(true);
        $subFlowFull = [];
        foreach ($subFlowList as $item) {
            $subFlowFull[$item] = $defaultFlow[$item];
            $subFlowFull[$item]['isnecessary'] = true;
        }
        if ($withNoChose) {
            $noChoseFlow = array_diff_key($defaultFlow, $subFlowFull);
            $subFlowFull += $noChoseFlow;
        }
        return $subFlowFull;
    }

    //获取项目流程标签
    public function getProjectFlowCode($projectId) {
        $redisClient = Redis::connect('projectflow');
        $flowKey = 'projectflowid:' . $projectId;
        //查缓存
        if ($redisClient->exists($flowKey)) {
            $tagCode = $redisClient->get($flowKey);
        } else {
            $sql = 'select tagcodelist from ProjectFlow where projectid = ? and status = ?';
            $tagCode = Db::selectOne($sql, [$projectId, '01']);
            if (!$tagCode) {
                return [];
            }
            $tagCode = $tagCode['tagcodelist'];
            //加入缓存 过期一周
            $redisClient->setex($flowKey, 3600 * 24 * 7, $tagCode);
        }
        return $tagCode;
    }

    //获取项目流程所有信息
    public function getProjectFlowFull($projectId) {
        $tagCode = $this->getProjectFlowCode($projectId);
        $flowList = explode(',', $tagCode);
        $caseFlowModel = new CaseFlow();
        $defaultFlow = $caseFlowModel->getDefaultFlow(true);
        $fullFlow = [];
        foreach ($flowList as $item) {
            $fullFlow[$item] = $defaultFlow[$item];
            $fullFlow[$item]['isnecessary'] = true;
        }
        $noChoseFlow = array_diff_key($defaultFlow, $fullFlow);
        $fullFlow += $noChoseFlow;
        return $fullFlow;
    }

    /**
     * 获取流程标签信息
     * @param $flowAt
     * @param $flowAtStatus
     * @return mixed
     * @throws \Exception
     */
    public function getFlowInfo($flowAt, $flowAtStatus = '') {
        $flowList = $this->getDefaultFlow(true);
        if ($flowAtStatus) {
            return $flowList[$flowAt]['child'][$flowAtStatus];
        }
        return $flowList[$flowAt];
    }

    /**
     * 将code关联索引数组转换为无索引数组
     * @param $flowList
     * @return array
     */
    public function transFlowToNotAssoc($flowList) {
        foreach ($flowList as &$item) {
            $item['child'] = array_values($item['child']);
        }
        return array_values($flowList);
    }

    /**
     * 获取不带未选中标签的完整标签列表
     * @param $subId
     * @return array
     * @throws \Exception
     */
    public function getSubFlow($subId) {
        $result = (new CustomerModel())->myCostumer(['subid' => $subId]);
        if (empty($result) || !in_array($subId, array_column($result, 'subid'))) {
            return [];
        }
        //todo 添加redis存储，提升查询效率
        $subFlow = $this->getSubFlowFull($subId);
        return $subFlow;
    }

    /**
     * 根据当前流程节点获取下一节点位置
     * @param $subId
     * @param $currentFlow
     * @return string
     * @throws \Exception
     */
    public function getNextFlow($subId, $currentFlow) {
        $flowList = $this->getSubFlow($subId);
        $flowAtList = array_keys($flowList);
        unset($flowList);
        for ($i = 0; $i < count($flowAtList); $i++) {
            if ($flowAtList[$i] == $currentFlow && isset($flowAtList[$i + 1])) {
                return $flowAtList[$i + 1];
            }
        }
        return '';
    }

    /**
     * Notes:项目流程下个节点
     * @param $projectId
     * @param $currentFlow 当前节点
     * @return string
     */
    public function getProjectNextFlow($projectId, $currentFlow) {
        $flowList = explode(',', $this->getProjectFlowCode($projectId));
        $currentFlowKey = array_search($currentFlow, $flowList);
        $nextFlowKey = $currentFlowKey + 1;
        return $flowList[$nextFlowKey] ?? '';
    }

    /**
     * Notes: 翻译标签
     * @param $row
     * @param string $flowatField 原数组中一级标签字段名
     * @param string $flowatstatusField 原数组中二级标签字段名
     * @return mixed
     * @throws \Exception
     */
    public function rowTrans($row, $flowatField = 'flowat', $flowatstatusField = 'flowatstatus') {
        $caseFlowList = config('app.global_caseflow');
        if (!is_file($caseFlowList)) {
            throw new RuntimeException('职位流程未定义');
        }
        $caseFlow = include $caseFlowList;
        foreach ($row as $k => $item) {
            $row[$k][$flowatField . '_name'] = isset($item[$flowatField]) ? $caseFlow[$item[$flowatField]]['name'] : '';
            $row[$k][$flowatstatusField . '_name'] = isset($item[$flowatstatusField]) ? $caseFlow[$item[$flowatField]]['child'][$item[$flowatstatusField]]['name'] : '';
        }
        return $row;
    }

}